home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr26
/
netprog.zip
/
NETPROG.TAR
/
xnsecho
/
xnsecho.c
< prev
Wrap
C/C++ Source or Header
|
1989-12-17
|
3KB
|
134 lines
/*
* This is an example of an XNS echo client.
* It uses the protocol defined in the Xerox manual "Internet Transport
* Protocols" (XNSS 028112, Dec. 1981), Chapter 6, pp. 37-38.
* Notice that on 4.3BSD systems, the kernel handles these requests,
* if a server isn't listening on the echo port.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netns/ns.h>
#include <netns/idp.h>
#define ECHO_SERV_ADDR "123:02.07.01.00.6d.82:2"
/* <netid>:<hostid>:<port> */
/* the <port> of 2 is the well-known port
(XNS "socket") for an XNS echo server */
#define ECHO_REQUEST 1 /* client sends a request as operation field */
#define ECHO_REPLY 2 /* server responds with this as op field */
#define OP_SIZE sizeof(short)
/* size of the operation field at front of packet */
#define MAXLINE 255
extern int rtt_d_flag; /* defined in the rtt.h header file */
/* to print the RTT timing info */
char *pname;
main(argc, argv)
int argc;
char *argv[];
{
FILE *fp, *fopen();
register int i, sock;
struct idp idp_hdr;
pname = argv[0];
--argc; ++argv;
rtt_d_flag = 1; /* to print the RTT timing info */
/*
* Create an IDP socket, bind any local address and record the
* server's address.
*/
if ( (sock = idp_open(ECHO_SERV_ADDR, (char *) 0, 0)) < 0)
err_sys("can't create IDP socket");
/*
* Set the socket option for default headers on output.
* We set the packet type field of the IDP header to NSPROTO_ECHO.
* Note that all the system uses from this structure is the packet
* type field (idp_pt), and this will be the packet type on all
* datagrams sent on this socket.
* Note that the packet type field is a single byte, so there are
* no byte-ordering problems.
*/
idp_hdr.idp_pt = NSPROTO_ECHO; /* packet type */
if (setsockopt(sock, 0, SO_DEFAULT_HEADERS,
(char *) &idp_hdr, sizeof(idp_hdr)) < 0)
err_sys("setsockopt error");
/*
* Main loop.
* For every command line argument (or stdin) call doit();
*/
i = 0;
fp = stdin;
do {
if (argc > 0 && (fp = fopen(argv[i], "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", pname, argv[i]);
continue;
}
doit(sock, fp);
} while (++i < argc);
close(sock);
exit(0);
}
/*
* Read the contents of the FILE *fp, write each line to the
* socket (to the server process), then read a line back from
* the socket and print it on the standard output.
*/
doit(sock, fp)
register int sock;
register FILE *fp;
{
int n, sendlen;
char *fgets();
char sendline[MAXLINE], recvline[MAXLINE];
while (fgets(sendline + OP_SIZE, MAXLINE, fp) != NULL) {
/*
* Set the first 2 bytes of the packet to ECHO_REQUEST.
*/
*( u_short * ) sendline = htons(ECHO_REQUEST);
/* op = echo request */
sendlen = strlen(sendline + OP_SIZE) + OP_SIZE;
if ( (n = dgsendrecv(sock, sendline, sendlen, recvline, MAXLINE,
(struct sockaddr *) 0, 0)) < 0)
err_sys("drsendrecv error");
/*
* There had better be at least 2 bytes in the datagram, and
* the first 2 bytes must be ECHO_REPLY.
*/
if (n < OP_SIZE)
err_dump("invalid length");
if ( (*(u_short *) recvline) != htons(ECHO_REPLY))
err_dump("unexpected operation field");
recvline[n] = 0; /* null terminate */
fputs(recvline + OP_SIZE, stdout);
}
if (ferror(fp))
err_sys("error reading file");
fclose(fp); /* close the FILE, leave the socket open */
}